/**
 * 
 */
package com.cn.practice.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

/**
 * 代理模式分静态代理和动态代理
 * spring的接口调用就是用代理模式实现的 用的动态代理
 * 静态代理就是写一个代理对象和被代理对象都实现代理接口
 * 代理对象实现代理接口的方法传入一个代理接口调用方法
 * 具体实现的时候这个代理接口传入被代理对象就能调用
 * @author zhangyang
 *
 */
public class ProxyPractice2 {
public static void main(String[] args) {
	
	/**
	 * 只写动态代理-JDK的动态代理 实现Proxy api
	 */
	UserProxy userProxy = new UserProxy(new UserDaoImpl());
	UserDao instance = (UserDao)userProxy.getProxyInstance();
	instance.getUser();
	/**
	 * Cglib实现动态代理-这个代理不需要写接口 
	 * 核心 实现MethodIntercaptor接口
	 * 重写intercept方法实现方法调用
	 * 使用Enhancer 生成一个被代理类的子类
	 */
	CglibUserProxy proxy = new CglibUserProxy(new UserDaoImpl());
	UserDaoImpl object = (UserDaoImpl)proxy.getProxyInstance();
	object.getUser();
}
}

interface UserDao{
	void getUser();
}

class UserDaoImpl implements UserDao{


	@Override
	public void getUser() {
		// TODO Auto-generated method stub
		System.out.println("当前被道理对象UserDaoImpl用户正在被获取");
	}
	
}

/**
 * JDK代理
 * @author zhangyang
 *
 */
class UserProxy{
	/**
	 * 被代理的对象
	 */
	Object target;
	
	
	public UserProxy(Object target) {
		super();
		this.target = target;
	}


	public Object getProxyInstance() {
		//获取代理对象的方法
		return Proxy.newProxyInstance(this.target.getClass().getClassLoader(), this.target.getClass().getInterfaces(), new InvocationHandler() {
			
			@Override
			public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
				// TODO Auto-generated method stub
				Object invoke = method.invoke(target, args);
				return invoke;
			}
		});
	}
}


class CglibUserProxy implements MethodInterceptor{
	/**
	 * 被代理的对象
	 */
	Object target;
	
	//构造方法
	public CglibUserProxy(Object target) {
		super();
		this.target = target;
	}

	public Object getProxyInstance() {
		Enhancer enhancer = new Enhancer();
		enhancer.setSuperclass(target.getClass());
		enhancer.setCallback(this);
		return enhancer.create();
	}
	@Override
	public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
		// TODO Auto-generated method stub
		System.out.println("Cglib代理启动");
		Object invoke = method.invoke(target, args);
		return invoke;
	}
	
 
}